#include "Tank.h"
#include <string.h>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <list>
using namespace std;
//请勿修改以上头文件
/*

您可以在这里添加您所需头文件

*/
#include "core.h"
#include "utils.h"

/*

您可以在这里添加您的自定义函数

*/

DataForAI gdata;

short destination[MAX_TANK_NUM];  //tank的当前目标=矿号+1
short resourceNeedCapture[MAX_SOURCE_NUM+1];//未被锁定的资源
//Point tankHistoryLastStep[MAX_TANK_NUM]; //tank上一步
//Point tankHistoryNextStep[MAX_TANK_NUM];//tank下一步
//Point tankHistoryNextStep4[MAX_TANK_NUM];
//Point tankHistoryLastStep4[MAX_TANK_NUM];
int NearestTankToSource[MAX_SOURCE_NUM]; //tank_num+1
int NearestTankToSourceDist[MAX_SOURCE_NUM];
short tankHistoryNextStep_Round=0;
Point tankHistoryLocation[MAX_TANK_NUM];
bool tankHistoryOderIsFIRE[MAX_TANK_NUM];
short tankHistoryLocationStaticTimes[MAX_TANK_NUM];
ofstream fout("Debug_Out.txt");
int roundCount=0;
bool Field[MAP_HEIGHT][MAP_WIDTH];


//平台0回合时调用此函数获取AI名称及坦克类型信息，请勿修改此函数声明。
extern "C" InitiateInfo chooseType()
{
	InitiateInfo Info;
	Info.tank[0]=Pioneer;
	Info.tank[1]=Striker;
	Info.tank[2]=Sniper;
	Info.tank[3]=Sniper;
	Info.tank[4]=Striker;
	strcpy(Info.aiName,"lgAI"); //AI名请勿使用中文。
	return Info;
}

Order makeNoharmOrder(DataForAI& data) {
    Order order;
    order.type = STOP;
    return order;
}

int choiceWeight(Choice& c) {
    int weight = 0;
    if(c.takeSourceStep == 1) {
        weight += 100;
    } else if(c.takeSourceStep == 2) {
        weight += 50;
    } else if(c.takeSourceStep == 3) {
        weight += 20;
    } else if(c.takeSourceStep <= 50) {
        weight += 10;
    }

    if(c.order.type == FIRE) {
       weight += 30;
    }

    if(c.willKill) {
       weight += 100;
    }

    return weight;
}

//平台从第1回合开始调用此函数获得每回合指令，请勿修改此函数声明。
extern "C" Order makeOrder(DataForAI data)
{
	int beginClock=clock();

    gdata = data;
    fout<<"---BEGIN---round "<<data.round<<" for tank "<<data.myID<<endl;

    Order order;
    order.type = STOP;

	TankData & tank = data.tank[data.myID];

	updateField(data);

    if(gdata.tank[gdata.myID].noharm==MAX_NOHARM_ROUND) { //刚出生
    	if(destination[gdata.myID])
    			  {
    				NearestTankToSource[destination[gdata.myID]-1]=0;
    				destination[gdata.myID]=0;
    			  }
    	//return order;
    	}

    if(tank.noharm > 0) {
        order = makeNoharmOrder(data);
    }
    if(order.type != STOP) {
        return order;
    }

    list<Choice> list_c1 = makeChoiceByBeaten(data);
    list<Choice> list_c2 = makeChoiceByAttack(data);
    //list<Choice> list_c3 = makeChoiceByFinding(data);
    list<Choice> list_c3 = makeChoiceByFinding2(data);
    list<Choice> list_c4 = makeChoiceByDefend(data);

    markChoiceType(list_c1, 'b');
    markChoiceType(list_c2, 'a');
    markChoiceType(list_c3, 'f');
    markChoiceType(list_c4, 'd');

    list<Choice> all;
    all.insert(all.end(), list_c1.begin(), list_c1.end());
    all.insert(all.end(), list_c2.begin(), list_c2.end());
    all.insert(all.end(), list_c3.begin(), list_c3.end());
    all.insert(all.end(), list_c4.begin(), list_c4.end());

    list<Choice>::iterator itr = all.begin();
    Choice best = *(all.begin());
    best.__weight = choiceWeight(best);
    itr ++;

    fout<<"Choices:"<<endl;
    fout<<"choice 1:\t";
    printChoice(best);
    fout<<endl;
    int i = 2;
    int best_i = 1;
    while(itr != all.end()) {
       itr->__weight = choiceWeight(*itr);
       fout<<"choice "<<i<<":\t";
       printChoice(*itr);
       fout<<endl;

       if(itr->__weight >= best.__weight) {
           best = *itr;
           best_i = i;
       }
       itr ++;
       i++;
    }

    fout<<"==best choice is "<<best_i<<endl;
    printChoice(best);
    int endClock = (clock()-beginClock);


    fout<<"\n-----END----round "<<data.round<<" for tank "<<data.myID<<endl;
    fout<<"\nTime cost: "<<endClock;
    if(endClock >= 48) {
    	fout<<"FATAL!!!Timeout!!!!"<<endl;
    } else {
    	fout<<endl;
    }
    fout<<endl;



    if(best.order.type==FIRE) tankHistoryOderIsFIRE[gdata.myID]=1;
    else tankHistoryOderIsFIRE[gdata.myID]=0;
    return best.order;
}
